package cn.jbolt.config.websocket;

import cn.hutool.core.util.StrUtil;
import cn.jbolt.ai.core.chain.AiAppChain;
import cn.jbolt.ai.core.chain.ChainCenter;
import cn.jbolt.util.JSONUtil;
import cn.jbolt.ai.app.service.AiAppService;
import cn.jbolt.ai.app.vo.SocketData;
import cn.jbolt.util.Result;
import com.jboltai.scheduler.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
public class JBoltAIWebSocketHandler extends TextWebSocketHandler {

    private static final Logger logger = LoggerFactory.getLogger(JBoltAIWebSocketHandler.class);

    @Autowired
    private AiAppService aiAppService;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.info("scoket已连接,默认会话id:{}", session.getId());
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        try {
            String payload = message.getPayload();
            logger.info("socket收到消息,会话id :{},消息体:{}", session.getId(), payload);
            SocketData data = JSONUtil.toObject(payload, SocketData.class);
            String action = data.getAction();
            if (StrUtil.isBlank(action)) {
                logger.error("消息的action为空，无法处理");
                return;
            }
            switch (action) {
                case SocketData.ACTION_PING:
                    session.sendMessage(new TextMessage(JSONUtil.createObjectNode().put("action","pong").toString()));
                    break;
                case SocketData.ACTION_REQUEST:
                case SocketData.ACTION_REGENERATE:
                    handleRequest(session, data);
                    break;
                case SocketData.ACTION_CANCEL:
                    logger.debug("请求[{}]被手动终止", data.getFlag() );
                    EventBus.cancel(data.getFlag());
                    break;
            }


        } catch (Exception e) {
            e.printStackTrace();
            logger.error("错误处理消息,会话id:{},异常原因:{} ", session.getId(), e.getMessage());
        }
    }

    private void handleRequest(WebSocketSession session, SocketData data) {
        //1. 首先从data中获取app，判断app是否有效
        Long appId = data.getApp();
        Result appResult = aiAppService.getAppById(appId);
        if (appResult.isError()) {
            logger.error("app无效,appId:{}", appId);
            throw new RuntimeException(appResult.getMsg());
        }
        //2. 获取事件链条
        AiAppChain chain = data.isDebugMode() ? ChainCenter.getDevAppChain(appId) : ChainCenter.getAppChain(appId);
        if (chain == null) {
            logger.error(data.isDebugMode() ? "应用的节点数据未找到，请重新点击试运行" : "应用的节点数据未找到");
            throw new RuntimeException(data.isDebugMode() ?"应用的节点数据未找到，请重新点击试运行" : "应用的节点数据未找到");
        }
        //3. 启动链条
        chain.start(data, session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        logger.error("scoket已关闭,默认会话id:{}", session.getId());
    }
}
